<?xml version='1.0' encoding='iso-8859-1'?>
<!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
	<head>
		<title>
			openchannel.c
			</title>
		<meta http-equiv='content-type' content='text/html;iso-8859-1'/>
		<meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
		<meta name='author' content='cmaier@cmassoc.net'/>
		<meta name='robots' content='noindex,nofollow'/>
		<link href='toolkit.css' rel='stylesheet' type='text/css'/>
		</head>
	<body>
		<div class='headerlink'>
			[<a href='nvrampeek.c.html' title=' nvrampeek.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='openport.c.html' title=' openport.c '>NEXT</a>]
			</div>
<pre>
/*====================================================================*
 *
 *   Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or 
 *   without modification, are permitted (subject to the limitations 
 *   in the disclaimer below) provided that the following conditions 
 *   are met:
 *
 *   * Redistributions of source code must retain the above copyright 
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above 
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *
 *   * Neither the name of Qualcomm Atheros nor the names of 
 *     its contributors may be used to endorse or promote products 
 *     derived from this software without specific prior written 
 *     permission.
 *
 *   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE 
 *   GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE 
 *   COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR 
 *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 *   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 *--------------------------------------------------------------------*/

/*====================================================================*
 *
 *   signed openchannel (struct channel * channel);
 *
 *   channel.h
 *
 *   open a raw ethernet channel;
 *
 *
 *   Contributor(s):
 *	Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
 *	Nathaniel Houghton &lt;nhoughto@qca.qualcomm.com&gt;
 *
 *--------------------------------------------------------------------*/

#ifndef OPENCHANNEL_SOURCE
#define OPENCHANNEL_SOURCE

#include &lt;unistd.h&gt;
#include &lt;memory.h&gt;
#include &lt;errno.h&gt;

#if defined (__linux__)
#	include &lt;net/if_arp.h&gt;
#	include &lt;netpacket/packet.h&gt;
#	include &lt;sys/ioctl.h&gt;
#elif defined (__APPLE__)
#	include &lt;sys/ioctl.h&gt;
#	include &lt;sys/stat.h&gt;
#	include &lt;fcntl.h&gt;
#	include &lt;stdlib.h&gt;
#elif defined (__OpenBSD__)
#	include &lt;sys/ioctl.h&gt;
#	include &lt;sys/stat.h&gt;
#	include &lt;sys/types.h&gt;
#	include &lt;fcntl.h&gt;
#	include &lt;stdlib.h&gt;
#elif defined (WINPCAP)
#	include &lt;string.h&gt;
#else
#error &quot;Unknown environment&quot;
#endif

#include &quot;../ether/channel.h&quot;
#include &quot;../tools/memory.h&quot;
#include &quot;../tools/flags.h&quot;
#include &quot;../tools/error.h&quot;

#if defined (__APPLE__) || defined (__OpenBSD__)
#	include &quot;../ether/gethwaddr.c&quot;
#endif

signed openchannel (struct channel * channel)

{

#if defined (__linux__)

	struct ifreq ifreq;
	struct sockaddr_ll sockaddr_ll =
	{
		PF_PACKET,
		0x0000,
		0x0000,
		ARPHRD_ETHER,
		PACKET_HOST,
		ETHER_ADDR_LEN,
		{
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00
		}
	};

/*
 *      raw packets require root privileges on linux; one does not have to be
 *      root when this program is installed setuid using 'chown root:root' and
 *      'chmod 4555';
 */

	if (geteuid ())
	{
		error (1, EPERM, ERROR_NOTROOT);
	}

	memset (&amp;ifreq, 0, sizeof (ifreq));
	sockaddr_ll.sll_protocol = htons (channel-&gt;type);
	if ((channel-&gt;fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == -1)
	{
		error (1, errno, &quot;%s&quot;, channel-&gt;ifname);
	}
	memcpy (ifreq.ifr_name, channel-&gt;ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel-&gt;fd, SIOCGIFINDEX, &amp;ifreq) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	channel-&gt;ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex;
	if (ioctl (channel-&gt;fd, SIOCGIFHWADDR, &amp;ifreq) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr));
	if (bind (channel-&gt;fd, (struct sockaddr *) (&amp;sockaddr_ll), sizeof (sockaddr_ll)) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	memcpy (channel-&gt;host, sockaddr_ll.sll_addr, sizeof (channel-&gt;host));
	if (ioctl (channel-&gt;fd, SIOCGIFFLAGS, &amp;ifreq) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	channel-&gt;ifstate = ifreq.ifr_flags;
	_setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST));
	_clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC));
	if (ioctl (channel-&gt;fd, SIOCSIFFLAGS, &amp;ifreq) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}

#else

	struct bpf_program bpf_program;
	static struct bpf_insn bpf_insn [] =
	{
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			12
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			18,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			10,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			1
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			8,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			2
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			6,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			3
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			5
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			4,
			0,
			0
		},
		{
			BPF_LD + BPF_W + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0xFFFFFFFF
		},
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0xFFFF
		},
		{
			BPF_LD + BPF_W + BPF_LEN,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_A,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_K,
			0,
			0,
			0
		}
	};

#if defined (__APPLE__) || defined (__OpenBSD__)

	struct ifreq ifreq;
	struct timeval timeval;
	struct bpf * bpf;
	char filename [sizeof (CHANNEL_BPFDEVICE) + 1];
	unsigned count;
	unsigned state;
	int stat_errno = 0;
	int open_errno = 0;
	for (count = 0; count &lt; 100; count++)
	{
		struct stat st;
		snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count);
		if (stat(filename, &amp;st) == -1)
		{
			stat_errno = errno;
			continue;
		}
		if ((channel-&gt;fd = open (filename, O_RDWR)) != -1)
		{
			break;
		}
		else
		{
			open_errno = errno;
		}
	}
	if (channel-&gt;fd == -1)
	{
		if (open_errno)
		{
			error (1, open_errno, &quot;Could not open bpf device&quot;);
		}
		else
		{
			error (1, stat_errno, &quot;No bpf device found&quot;);
		}
	}
	memcpy (ifreq.ifr_name, channel-&gt;ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel-&gt;fd, BIOCSETIF, &amp;ifreq) == -1)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	channel-&gt;bpf = bpf = malloc (sizeof (* bpf));
	if (ioctl (channel-&gt;fd, BIOCGBLEN, &amp;bpf-&gt;bpf_length) == -1)
	{
		error (1, errno, &quot;Can't determine buffer length: %s&quot;, ifreq.ifr_name);
	}
	bpf-&gt;bpf_bp = bpf-&gt;bpf_buffer = malloc (bpf-&gt;bpf_length);
	if (bpf-&gt;bpf_buffer == NULL)
	{
		error (1, errno, &quot;Can't allocate receive buffer&quot;);
	}

#if defined (__APPLE__)

	state = 0;
	if (ioctl (channel-&gt;fd, BIOCSSEESENT, &amp;state) == -1)
	{
		error (1, errno, &quot;Can't hide outgoing frames: %s&quot;, ifreq.ifr_name);
	}

#elif defined (__OpenBSD__)

	state = BPF_DIRECTION_OUT;
	if (ioctl (channel-&gt;fd, BIOCSDIRFILT, &amp;state) == -1)
	{
		error (0, errno, &quot;Can't hide outgoing frames&quot;);
	}

#else
#error &quot;Abandon all hope&quot;
#endif

	if (channel-&gt;capture &gt; 1000)
	{
		timeval.tv_sec = channel-&gt;capture / 1000;
		timeval.tv_usec = 0;
	}
	else
	{

#if defined (__MAC_10_6)

/*
 *	accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read
 *	operations to block indefinitely if no frames are waiting because tv_usec gets
 *      clobbered;
 */

		timeval.tv_sec = 1;
		timeval.tv_usec = 0;

#else

		timeval.tv_sec = 0;
		timeval.tv_usec = channel-&gt;capture * 1000;

#endif

	}
	if (ioctl (channel-&gt;fd, BIOCSRTIMEOUT, &amp;timeval) == -1)
	{
		error (1, errno, &quot;Can't set channel timeout: %s&quot;, ifreq.ifr_name);
	}
	state = 1;
	if (ioctl (channel-&gt;fd, BIOCIMMEDIATE, &amp;state) == -1)
	{
		error (1, errno, &quot;Can't set immediate mode: %s&quot;, ifreq.ifr_name);
	}

#if 1

	state = 1;
	if (ioctl (channel-&gt;fd, BIOCSHDRCMPLT, &amp;state) == -1)
	{
		error (1, errno, &quot;Can't set header complete mode: %s&quot;, ifreq.ifr_name);
	}

#endif

#if 1

	gethwaddr (channel-&gt;host, channel-&gt;ifname);

#else

	if (ioctl (channel-&gt;fd, SIOCGIFADDR, &amp;ifreq) &gt; 0)
	{
		error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
	}
	memcpy (channel-&gt;host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel-&gt;host));

#endif

	bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel-&gt;type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel-&gt;type;
	}
	bpf_insn [3].k = channel-&gt;host [0];
	bpf_insn [5].k = channel-&gt;host [1];
	bpf_insn [7].k = channel-&gt;host [2];
	bpf_insn [9].k = channel-&gt;host [3];
	bpf_insn [11].k = channel-&gt;host [4];
	bpf_insn [13].k = channel-&gt;host [5];
	if (ioctl (channel-&gt;fd, BIOCSETF, &amp;bpf_program) == -1)
	{
		error (1, errno, &quot;Can't store filter: %s&quot;, channel-&gt;ifname);
	}

#elif defined (WINPCAP) || defined (LIBPCAP)

	channel-&gt;ifname = getifname (channel-&gt;ifindex);
	gethwaddr (channel-&gt;host, channel-&gt;ifname);
	channel-&gt;socket = pcap_open_live (channel-&gt;ifname, 65536, 0, channel-&gt;capture, channel-&gt;errbuf);
	snprintf ((char *)(channel-&gt;ifname), strlen (channel-&gt;ifname), &quot;nic%d&quot;, channel-&gt;ifindex);
	if (!channel-&gt;socket)
	{
		error (1, errno, &quot;Can't open interface: %s&quot;, channel-&gt;ifname);
	}
	bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel-&gt;type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel-&gt;type;
	}
	bpf_insn [3].k = channel-&gt;host [0];
	bpf_insn [5].k = channel-&gt;host [1];
	bpf_insn [7].k = channel-&gt;host [2];
	bpf_insn [9].k = channel-&gt;host [3];
	bpf_insn [11].k = channel-&gt;host [4];
	bpf_insn [13].k = channel-&gt;host [5];
	if (pcap_setfilter (channel-&gt;socket, &amp;bpf_program) &lt; 0)
	{
		error (1, errno, &quot;Can't store filter: %s&quot;, channel-&gt;ifname);
	}
	if (pcap_setmintocopy (channel-&gt;socket, ETHER_MIN_LEN) &lt; 0)
	{
		error (1, errno, &quot;Can't set pcap mintocopy: %s&quot;, channel-&gt;ifname);
	}

#else
#error &quot;Unknown Environment&quot;
#endif
#endif

	return (0);
}

#endif


</pre>
		<div class='footerlink'>
			[<a href='nvrampeek.c.html' title=' nvrampeek.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='openport.c.html' title=' openport.c '>NEXT</a>]
			</div>
		</body>
	</html>
